/******************************************************************************
                         COPYRIGHT 1955-2008 by BUPT ISC.
                        北京邮电大学信息安全中心 版权所有
                           Web: http://www.bupt.edu.cn
 *******************************************************************************/
/*******************************************************************************
  文件名： list.c
  项目：   
  模块：   common
  作者：   zhuxiaobo
  版本：   0.1
  创建于:  2008-12-09 
  描述：
    链表的操作方法实现

  修改历史：
  日期： 修改人： 修改描述：
  
 *********************************************************************************/

#include <stdio.h>
#include <malloc.h>
#include <string.h>

#include "list.h"

/******************************************************************************
  函数名：createNode
  功能描述：
    链表节点的创建
    
  输入参数：
    void *pData:待写入节点的数据块起始地址
    int iLength:写入数据的长度
  输出参数：
    无 

  返回值：
    返回LIST_NODE *,节点创建失败则返回NULL,成功则返回节点创建的指针
 *****************************************************************************/

LIST_NODE *createNode( void *pData, int iLength)
{
    LIST_NODE *pstNodeTemp = NULL;

    if (pData == NULL)
        return NULL;
    pstNodeTemp = (LIST_NODE *)malloc(sizeof(LIST_NODE));/*新节点分配空间*/
    if (pstNodeTemp == NULL)
        return NULL;
    pstNodeTemp->pData = (void *)malloc(iLength);/*新节点的数据域分配空间*/
    if (pstNodeTemp->pData == NULL)
        return NULL;
    pstNodeTemp->iDataLen = iLength;
    pstNodeTemp->pstNext = NULL;
    pstNodeTemp->pstPrior = NULL;
    memcpy(pstNodeTemp->pData, pData, iLength);
    return pstNodeTemp;
}

/******************************************************************************
  函数名：freeNode
  功能描述：
     释放节点空间，包括节点数据域的空间和节点本身分配的空间
  输入参数：
     LIST_NODE *pstNodeTemp:待释放的节点指针
  输出参数：
    无
  注意：若节点pData域数据结构再次分配空间，则要手动释放内存
  返回值：
    节点释放成功则返回true,失败则返回false 
 *****************************************************************************/

bool freeNode(LIST_NODE *pstNodeTemp)
{
    if (pstNodeTemp == NULL || pstNodeTemp->pData == NULL)
        return false;
    free(pstNodeTemp->pData);
    pstNodeTemp->pData = NULL;
    free(pstNodeTemp);
    return true;
}

/******************************************************************************
  函数名：initList
  功能描述：
    链表的初始化 
  输入参数：
    LINK_LIST *pstList:初始化链表 

  输出参数：
    无

  返回值：
    操作成功则返回true,失败则返回false 
 *****************************************************************************/

bool initList(LINK_LIST *pstList)
{
    if (pstList == NULL)
        return false;
    pstList->iCount = 0;
    pstList->pstHead = NULL;
    pstList->pstTail = NULL;
    return true;
}

/******************************************************************************
  函数名：createListHead
  功能描述：
    链表头节点的建立
  输入参数：
    LINK_LIST *pstList:已知链表
    LIST_NODE *pstNodeTemp:待插入的头节点 

  输出参数：
    无

  返回值：
    操作成功则返回true,失败则返回false 
 *****************************************************************************/

bool createListHead(LINK_LIST *pstList, LIST_NODE *pstNodeTemp)
{
    if (pstList == NULL || pstNodeTemp == NULL)
        return false;
    pstList->pstHead = pstNodeTemp;
    pstList->pstTail = pstNodeTemp;
    pstList->pstHead->pstPrior = NULL;
    pstList->pstTail->pstNext = NULL;
    pstList->iCount++;
    return true;
}

/******************************************************************************
  函数名：addListTail
  功能描述：
    链表的尾插法
  输入参数：
    LINK_LIST *pstList:已知链表
    LIST_NODE *pstNodeTemp:待插入的节点 

  输出参数：
    无

  返回值：
    操作成功则返回true,失败则返回false 
 *****************************************************************************/

bool addListTail(LINK_LIST *pstList, LIST_NODE *pstNodeTemp)
{
    if (pstList == NULL || pstNodeTemp == NULL)
        return false;
    if (pstList->pstTail == NULL)          /*尾节点不存在,即为空链表*/
    {
        pstList->pstTail = pstNodeTemp;
        pstList->pstTail->pstNext = NULL;
        pstList->pstHead = pstList->pstTail;
        pstList->pstHead->pstPrior = NULL;
        pstList-> iCount++;
        return true;
    }
    pstList->pstTail->pstNext = pstNodeTemp;
    pstNodeTemp->pstPrior = pstList->pstTail;
    pstList->pstTail = pstNodeTemp;
    pstList->pstTail->pstNext = NULL;
    pstList->iCount++;
    return true;
}

/******************************************************************************
  函数名：insertListAfter
  功能描述：
    在链表的当前节点的后面插入节点
  输入参数：
    LINK_LIST *pstList:已知链表
    LIST_NODE *pstCurNode:当前节点
    LIST_NODE *pstNodeTemp:待插入节点

  输出参数：
    无

  返回值：
    操作成功则返回true,失败则返回false 
 *****************************************************************************/

bool insertListAfter(LINK_LIST *pstList, LIST_NODE *pstCurNode, LIST_NODE *pstNodeTemp)
{
    if (pstList == NULL || pstCurNode == NULL || pstNodeTemp == NULL)
        return false;
    if (pstList->pstTail == NULL)
    {
        printf("链表为空");
        return false;
    }
    if (pstCurNode == pstList->pstTail)/*如果当前节点是尾节点的话，则直接加在尾节点之后*/
    {
        pstList->pstTail->pstNext = pstNodeTemp;
        pstNodeTemp->pstPrior = pstList->pstTail;
        pstList->pstTail = pstNodeTemp;
        pstList->pstTail->pstNext = NULL;
        pstList->iCount++;
        return true;
    }
    pstNodeTemp->pstNext = pstCurNode->pstNext;
    pstCurNode->pstNext->pstPrior = pstNodeTemp;
    pstCurNode->pstNext = pstNodeTemp;
    pstNodeTemp->pstPrior = pstCurNode;
    pstList->iCount++;
    return true;
}

/******************************************************************************
  函数名：delListNode
  功能描述：
    删除当前节点 
  输入参数：
    LINK_LIST *pstList:已知链表
    LIST_NODE *pstCurNode:当前节点

  输出参数：
    无

  返回值：
    操作成功则返回true,失败则返回false 
 *****************************************************************************/

bool delListNode(LINK_LIST *pstList, LIST_NODE *pstCurNode)
{
    if (pstList == NULL || pstCurNode == NULL)
        return false;
    if (pstCurNode == pstList->pstTail && pstCurNode == pstList->pstHead)/*若当前节点是唯一节点*/
    {
        freeNode(pstCurNode);
        pstList->pstHead = NULL;
        pstList->pstTail = NULL;
        pstList->iCount--;
        return true;
    }
    if (pstCurNode == pstList->pstHead)/*若当前节点是头节点*/
    {
        pstList->pstHead = pstList->pstHead->pstNext;
        freeNode(pstCurNode);
        pstList->pstHead->pstPrior = NULL;
        pstList->iCount--;
        return true;
    }
    if (pstCurNode == pstList->pstTail)/*若当前节点是尾节点*/
    {
        pstList->pstTail = pstList->pstTail->pstPrior;
        freeNode(pstCurNode);
        pstList->pstTail->pstNext = NULL;
        pstList->iCount--;
        return true;
    }
    pstCurNode->pstPrior->pstNext = pstCurNode->pstNext;
    pstCurNode->pstNext->pstPrior = pstCurNode->pstPrior;
    freeNode(pstCurNode);
    pstList->iCount--;
    return true;
}

/******************************************************************************
  函数名：freeList
  功能描述：
    释放链表空间,并将链表设为空表
  输入参数：
    LINK_LIST *pstList:已知链表

  输出参数：
    无

  返回值：
    操作成功则返回true,失败则返回false 
 *****************************************************************************/

bool freeList(LINK_LIST *pstList)
{
    LIST_NODE *pstNodeTemp = NULL;
    LIST_NODE *pstNodeTrav = NULL;

    if (pstList == NULL || pstList->pstHead == NULL)
        return false;
    pstNodeTrav = pstList->pstHead;
    pstNodeTemp = pstList->pstHead;
    while (pstNodeTemp != pstList->pstTail)
    {
        pstNodeTemp = pstNodeTemp->pstNext;
        freeNode(pstNodeTrav);
        pstNodeTrav = NULL;
        pstNodeTrav = pstNodeTemp;   
    }
    freeNode(pstList->pstTail);
    initList(pstList);
    return true;
}
